package com.bfxy.order.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.bfxy.order.constants.OrderStatus;
import com.bfxy.order.entity.Order;
import com.bfxy.order.mapper.OrderMapper;
import com.bfxy.order.service.OrderService;
import com.bfxy.order.service.producer.OrderlyProducer;
import com.bfxy.order.utils.FastJsonConvertUtil;
import com.bfxy.store.api.StoreServiceApi;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    //dubbo的新的注解：@Reference，将StoreServiceApi注入进来
    @Reference(version = "1.0.0",
            application = "${dubbo.application.id}",
            interfaceName = "com.bfxy.store.service.StoreServiceApi",
            check = false,
            timeout = 3000, //超时时间
            retries = 0     //只允许请求一次成功则购买成功，不然的话由用户重新下订单。
    )
    private StoreServiceApi storeServiceApi;

    @Autowired
    private OrderlyProducer orderlyProducer;

    @Override
    public boolean createOrder(String cityId, String platformId, String userId, String supplierId, String goodsId) {
        boolean flag = true;//返回值
        try {
            //创建订单
            Order order = new Order();
            order.setOrderId(UUID.randomUUID().toString().substring(0, 32));//订单号
            order.setOrderType("1");//订单类型
            order.setCityId(cityId);//城市ID
            order.setPlatformId(platformId);//平台ID
            order.setUserId(userId);//用户ID
            order.setSupplierId(supplierId);//供应商ID
            order.setGoodsId(goodsId);//商品ID
            order.setOrderStatus(OrderStatus.ORDER_CREATED.getValue());//订单状态
            order.setRemark("");//描述

            Date currentTime = new Date();
            order.setCreateBy("admin");//创建人
            order.setCreateTime(currentTime);//创建时间
            order.setUpdateBy("admin");//更新人
            order.setUpdateTime(currentTime);//更新时间

            //使用dubbo服务，调用库存中的方法
            int currentVersion = storeServiceApi.selectVersion(supplierId, goodsId);//当前版本号
            //更新库存。updateRetCount
            int updateRetCount = storeServiceApi.updateStoreCountByVersion(currentVersion, supplierId, goodsId, "admin", currentTime);

            //有一条记录被更新了，就可以入库了。
            if (updateRetCount == 1) {
                // TODO:	如果出现SQL异常 入库失败, 那么要对 库存的数量 和版本号进行回滚操作
                orderMapper.insertSelective(order);
            }
            //	没有更新成功 原因：1 高并发时乐观锁生效   2 库存不足
            else if (updateRetCount == 0) {
                flag = false;    //	下单标识失败
                //查询当前库存
                int currentStoreCount = storeServiceApi.selectStoreCount(supplierId, goodsId);
                if (currentStoreCount == 0) {
                    //这里应该返回一个具体的对象：{flag:false , messageCode: 003 , message: 当前库存不足}
                    System.err.println("-----当前库存不足...");
                } else {
                    //这里应该返回一个具体的对象：{flag:false , messageCode: 004 , message: 乐观锁生效}
                    System.err.println("-----乐观锁生效...");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 	具体捕获的异常是什么异常
            flag = false;
        }

        return flag;
    }

    // 包裹的topic
    public static final String PKG_TOPIC = "pkg_topic";

    // 包裹的tags
    public static final String PKG_TAGS = "pkg";

    // 發順序消息，創建包裹。
    @Override
    public void sendOrderlyMessage4Pkg(String userId, String orderId) {
        // 他發的是一批消息，有同一個業務ID
        List<Message> messageList = new ArrayList<>();

        // 物流信息
        Map<String, Object> param1 = new HashMap<String, Object>();
        param1.put("userId", userId);
        param1.put("orderId", orderId);
        param1.put("text", "创建包裹操作---1");// 第一步操作，第一條消息

        String key1 = UUID.randomUUID().toString() + "$" + System.currentTimeMillis();// 消息的key
        Message message1 = new Message(PKG_TOPIC, PKG_TAGS, key1, FastJsonConvertUtil.convertObjectToJSON(param1).getBytes());// 組裝消息

        messageList.add(message1);// 將第一條消息加到messageList中


        Map<String, Object> param2 = new HashMap<String, Object>();
        param2.put("userId", userId);
        param2.put("orderId", orderId);
        param2.put("text", "发送物流通知操作---2");// 第二步操作，第二條消息

        String key2 = UUID.randomUUID().toString() + "$" + System.currentTimeMillis();
        Message message2 = new Message(PKG_TOPIC, PKG_TAGS, key2, FastJsonConvertUtil.convertObjectToJSON(param2).getBytes());

        messageList.add(message2);

        //	顺序消息投递 是应该按照 供应商ID 与topic 和 messageQueueId 进行绑定对应的
        //  這裡用的是supplier_id

        Order order = orderMapper.selectByPrimaryKey(orderId);// 查詢supplier_id
        int messageQueueNumber = Integer.parseInt(order.getSupplierId());// 將supplier_id作為messageQueueID

        //对应的顺序消息的生产者 把messageList 发出去
        orderlyProducer.sendOrderlyMessages(messageList, messageQueueNumber);
    }


}
